/***
 * @Author: 玄绮 shijiahansi@qq.com
 * @Date: 2024-05-29 16:40:11
 * @LastEditors: 玄绮 shijiahansi@qq.com
 * @LastEditTime: 2024-05-29 16:40:11
 * @FilePath: \client\src\app\client\ChatClient.cpp
 * @Description:
 * @
 * @Copyright (c) 2024 by 玄绮, All Rights Reserved.
 */

#include "ChatClient.h"

ChatClient::ChatClient() : QObject(nullptr) {
}

ChatClient::~ChatClient() {
}

void ChatClient::send_pack(google::protobuf::Message& msg, PackgeType type) {
    auto pack                = std::make_shared<Packge>();
    pack->header.packge_type = type;
    pack->encode(&msg);

    send_packge(pack);
}

void ChatClient::request(Method method, ::std::map<String, String>& args) {
    auto req = Request{};
    req.set_method(method);
    for (auto&& i : args) {
        (*req.mutable_args())[i.first] = i.second;
    }

    send_pack(req, PackgeType::Request);
}

void ChatClient::request(Method method, ::google::protobuf::Message& arg) {
    auto req = Request{};
    req.set_method(method);

    String str;
    arg.SerializeToString(&str);
    (*req.mutable_data()).assign(str);
    send_pack(req, PackgeType::Request);
}

void ChatClient::request(Method method, String& arg) {
    auto req = Request{};
    req.set_method(method);
    req.set_data(arg);
    send_pack(req, PackgeType::Request);
}

void ChatClient::request(Method method) {
    auto req = Request{};
    req.set_method(method);

    send_pack(req, PackgeType::Request);
}

void ChatClient::message(Message msg) {
    send_pack(msg, PackgeType::Message);
}

void ChatClient::Login(String account, String passowd) {
    auto user = Account{};
    user.set_account(account);  // 发生异常: CPP/std::bad_alloc Unhandled exception at 0x00007FFE3113543C in boostChat.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0000009780AF9AE0.
    user.set_password(passowd);

    std::cout << user.DebugString() << std::endl;

    request(Method::Login, user);
}

void ChatClient::Register(RegisterInfo info) {
    request(Method::Register, info);
}

void ChatClient::VerifyVerificationCode(String code) {
    request(Method::VerifyVerificationCode, code);
}

void ChatClient::SendVerificationCode(String bind) {
    request(Method::SendVerificationCode, bind);
}

void ChatClient::GetUserInfo(String userid) {
    std::map<String, String> args;
    args["userId"] = userid;
    request(Method::GetUserInfo, args);
}

void ChatClient::ChangUserInfo(UserInfo info) {
    request(Method::ChangUserInfo, info);
}

void ChatClient::SearchAuthor(String text) {
    std::map<String, String> args;
    args["text"] = text;
    request(Method::SearchAuthor, args);
}

void ChatClient::AddFriends(String userid) {
    std::map<String, String> args;
    args["userId"] = userid;
    request(Method::AddFriends, args);
}

void ChatClient::DelFriends(String userid) {
    std::map<String, String> args;
    args["userId"] = userid;
    request(Method::DelFriends, args);
}

void ChatClient::CreateGroup(ChatRoomInfo info) {
    request(Method::CreateGroup, info);
}

void ChatClient::CreateRoom(ChatRoomInfo info) {
    request(Method::CreateRoom, info);
}

void ChatClient::JoinGroup(String roomid) {
    std::map<String, String> args;
    args["roomId"] = roomid;
    request(Method::JoinGroup, args);
}

void ChatClient::QuitGroup(String roomid) {
    std::map<String, String> args;
    args["roomId"] = roomid;
    request(Method::QuitGroup, args);
}

void ChatClient::SetAccount(Account account) {
    request(Method::SetAccount, account);
}

void ChatClient::SetUserInfo(UserInfo info) {
    request(Method::SetUserInfo, info);
}

void ChatClient::GetFriendList() {
    request(Method::GetFriendList);
}

void ChatClient::GetRoomList() {
    request(Method::GetRoomList);
}

void ChatClient::GetRoomMembers(String roomid) {
    std::map<String, String> args;
    args["roomId"] = roomid;
    request(Method::GetRoomMembers, args);
}

void ChatClient::SearchGroup(String text) {
    std::map<String, String> args;
    args["text"] = text;
    request(Method::SearchGroup, args);
}

void ChatClient::pack_handler(Packge::shared_ptr pack) {
    switch (pack->header.packge_type) {
        case PackgeType::Response:
            response_handler(pack);
            break;
        case PackgeType::Message:
            message_handler(pack);
            break;
        default:
            break;
    }
}

void ChatClient::message_handler(Packge::shared_ptr pack) {
    auto msg = std::make_shared<Message>();
    pack->decode(msg.get());

    msg->PrintDebugString();
    onMessage(msg);
}

void ChatClient::response_handler(Packge::shared_ptr pack) {
    Response res;
    pack->decode(&res);

    res.PrintDebugString();

    switch (res.method()) {
        case Method::Register:
            response_Register(res);
            break;
        case Method::Login:
            response_Login(res);
            break;
        case Method::GetUserInfo:
            response_GetUserInfo(res);
            break;
        case Method::ChangUserInfo:
            response_ChangUserInfo(res);
            break;
        case Method::SearchAuthor:
            response_SearchAuthor(res);
            break;
        case Method::SearchGroup:
            response_SearchGroup(res);
            break;
        case Method::AddFriends:
            response_AddFriends(res);
            break;
        case Method::DelFriends:
            response_DelFriends(res);
            break;
        case Method::CreateGroup:
            response_CreateGroup(res);
            break;
        case Method::JoinGroup:
            response_JoinGroup(res);
            break;
        case Method::QuitGroup:
            response_QuitGroup(res);
            break;
        case Method::CreateRoom:
            response_CreateRoom(res);
            break;
        case Method::SetAccount:
            response_SetAccount(res);
            break;
        case Method::SetUserInfo:
            response_SetUserInfo(res);
            break;
        case Method::GetFriendList:
            response_GetFriendList(res);
            break;
        case Method::GetRoomList:
            response_GetRoomList(res);
            break;
        case Method::GetRoomMembers:
            response_GetRoomMembers(res);
            break;
        case Method::SendVerificationCode:
            response_SendVerificationCode(res);
            break;
        case Method::VerifyVerificationCode:
            response_VerifyVerificationCode(res);
            break;
        default:
            break;
    }
}

void ChatClient::response_Register(Response& res) {
    auto user = std::make_shared<UserInfo>();
    if (res.error_code() == 0)
        user->ParseFromString(res.data());
    onRegister(res.error_code(), res.message(), user);
}

void ChatClient::response_Login(Response& res) {
    auto user = std::make_shared<UserInfo>();
    if (res.error_code() == 0)
        user->ParseFromString(res.data());
    onLogin(res.error_code(), res.message(), user);
}

void ChatClient::response_GetUserInfo(Response& res) {
    auto user = std::make_shared<UserInfo>();
    if (res.error_code() == 0)
        user->ParseFromString(res.data());
    onGetUserInfo(res.error_code(), res.message(), user);
}

void ChatClient::response_ChangUserInfo(Response& res) {
    auto user = std::make_shared<UserInfo>();
    if (res.error_code() == 0)
        user->ParseFromString(res.data());
    onChangUserInfo(res.error_code(), res.message(), user);
}

void ChatClient::response_SearchAuthor(Response& res) {
    std::vector<std::shared_ptr<UserInfo>> users;
    if (res.error_code() == 0) {
        for (auto&& i : res.datas()) {
            auto info = std::make_shared<UserInfo>();
            info->ParseFromString(i);
            users.push_back(info);
        }
    }
    onSearchAuthor(res.error_code(), res.message(), users);
}

void ChatClient::response_SearchGroup(Response& res) {
    std::vector<std::shared_ptr<ChatRoomInfo>> rooms;
    if (res.error_code() == 0) {
        for (auto&& i : res.datas()) {
            auto info = std::make_shared<ChatRoomInfo>();
            info->ParseFromString(i);
            rooms.push_back(info);
        }
    }
    onSearchGroup(res.error_code(), res.message(), rooms);
}

void ChatClient::response_AddFriends(Response& res) {
    auto info = std::make_shared<FriendInfo>();
    if (res.error_code() == 0)
        info->ParseFromString(res.data());
    onAddFriends(res.error_code(), res.message(), info);
}

void ChatClient::response_DelFriends(Response& res) {
    String firendId = res.data();
    onDelFriends(res.error_code(), res.message(), firendId);
}

void ChatClient::response_CreateGroup(Response& res) {
    auto info = std::make_shared<ChatRoomInfo>();
    if (res.error_code() == 0)
        info->ParseFromString(res.data());
    onCreateGroup(res.error_code(), res.message(), info);
}

void ChatClient::response_JoinGroup(Response& res) {
    auto info = std::make_shared<ChatRoomInfo>();
    if (res.error_code() == 0)
        info->ParseFromString(res.data());
    onCreateGroup(res.error_code(), res.message(), info);
}

void ChatClient::response_QuitGroup(Response& res) {
    onQuitGroup(res.error_code(), res.message(), res.data());
}

void ChatClient::response_CreateRoom(Response& res) {
    auto info = std::make_shared<ChatRoomInfo>();
    if (res.error_code() == 0)
        info->ParseFromString(res.data());
    onCreateRoom(res.error_code(), res.message(), info);
}

void ChatClient::response_SetAccount(Response& res) {
    onSetAccount(res.error_code(), res.message());
}

void ChatClient::response_SetUserInfo(Response& res) {
    auto info = std::make_shared<UserInfo>();
    if (res.error_code() == 0)
        info->ParseFromString(res.data());
    onSetUserInfo(res.error_code(), res.message(), info);
}

void ChatClient::response_GetFriendList(Response& res) {
    std::vector<std::shared_ptr<FriendInfo>> users;
    if (res.error_code() == 0) {
        for (auto&& i : res.datas()) {
            auto info = std::make_shared<FriendInfo>();
            info->ParseFromString(i);
            users.push_back(info);
        }
    }
    onGetFriendList(res.error_code(), res.message(), users);
}

void ChatClient::response_GetRoomList(Response& res) {
    std::vector<std::shared_ptr<ChatRoomInfo>> rooms;
    if (res.error_code() == 0) {
        for (auto&& i : res.datas()) {
            auto info = std::make_shared<ChatRoomInfo>();
            info->ParseFromString(i);
            rooms.push_back(info);
        }
    }
    onGetRoomList(res.error_code(), res.message(), rooms);
}

void ChatClient::response_GetRoomMembers(Response& res) {
    std::vector<std::shared_ptr<UserInfo>> users;
    if (res.error_code() == 0) {
        for (auto&& i : res.datas()) {
            auto info = std::make_shared<UserInfo>();
            info->ParseFromString(i);
            users.push_back(info);
        }
    }
    onGetRoomMembers(res.error_code(), res.message(), res.data(), users);
}

void ChatClient::response_VerifyVerificationCode(Response& res) {
    onVerifyVerificationCode(res.error_code(), res.message());
}

void ChatClient::response_SendVerificationCode(Response& res) {
    onSendVerificationCode(res.error_code(), res.message(), res.data());
}
